#include "stdafx.h"
#include "../scriptmgr.h"
#include "./luaex.h"

LuaEx::LuaEx()
{
	ScriptMgr::GetInstance();	//make sure get luaState
}

LuaEx::~LuaEx()
{

}

void LuaEx::SetLuaState(lua_State* luaState)
{
	m_luaState = luaState;
}

lua_State* LuaEx::GetLuaState()
{
	return m_luaState;
}

luaobj LuaEx::LoadFunc(const char* funcName)
{
	if (!funcName)
	{
		return m_nullObj;
	}

	const char dot = '.';
	int table = LUA_GLOBALSINDEX;
	const char * pdot = NULL;

	do
	{
		pdot = strchr(funcName, dot);
		size_t len = pdot ? pdot - funcName : strlen(funcName);

		lua_pushlstring(m_luaState, funcName, len);
		lua_gettable(m_luaState, table);

		if (table == -2)
			lua_remove(m_luaState, table);
		else
			table = -2;

		if (lua_isnil(m_luaState, -1))
		{
			lua_pop(m_luaState, 1);
			return m_nullObj;
		}

		if (pdot)
		{
			pdot++;
			funcName = pdot;
		}
	}while(pdot);

	if (lua_isfunction(m_luaState, -1))
	{
		luaobj funcObj;
		funcObj->InitObj(luaL_ref(m_luaState, LUA_REGISTRYINDEX));
		return funcObj;
	}
	else
	{
		lua_pop(m_luaState, 1);
		//lua_pushfstring(m_luaState, "%s is not a function.", funcName);
		return m_nullObj;
	}
}

luathread LuaEx::NewThread()
{
	luathread newthread;
	return newthread;
}

bool LuaEx::CallFunc(luaobj& funcobj)
{
	return CallFuncEx(m_luaState, funcobj);
}

bool LuaEx::CallThreadFunc(luathread& td, luaobj& funcobj)
{
	return CallFuncEx(td->GetThreadState(), funcobj);
}

bool LuaEx::CallFuncEx(lua_State* luaState, luaobj& funcobj)
{
	if (NULL_OBJECT == funcobj->GetObj())
	{
		return false;
	}

	funcobj->PushObj(luaState);
	if (0 != lua_pcall(luaState, 0, 0, 0))
	{
		//LuaEx::ErrorFunc();
		lua_pop(luaState, 1);
		return false;
	}

	return true;
}